package me.zhengjie.server.impl;


import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.zhengjie.controller.InboundController;
import me.zhengjie.controller.merge.MergeTest;
import me.zhengjie.controller.test.DropGoodTest;
import me.zhengjie.dao.*;
import me.zhengjie.dao.dto.MergeTaskQueryCriteria;
import me.zhengjie.enums.InboundStatusEnum;
import me.zhengjie.enums.PriorityEnum;
import me.zhengjie.network.MesNetworkRequest;
import me.zhengjie.network.WcsNetworkRequest;
import me.zhengjie.server.*;
import me.zhengjie.utils.*;
import me.zhengjie.vo.Inbound.MesMaterialVo;
import me.zhengjie.vo.merge.*;
import me.zhengjie.enums.ConstantStatus;
import me.zhengjie.mapper.MergeTaskMapper;
import me.zhengjie.mapper.StoreTotalMapper;
import me.zhengjie.vo.OutBoundTaskToWcsVo;
import me.zhengjie.vo.Result;
import me.zhengjie.vo.mes.ResponseResult;
import me.zhengjie.vo.wcs.ResponseTaskToWcsVo;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

@Service
public class MergeTaskServiceImpl extends ServiceImpl<MergeTaskMapper, MergeTaskDao> implements MergeTaskService {

    private static final Logger mergeTaskLog = LoggerFactory.getLogger("mergeTask");

    @Resource
    private StoreTotalMapper storeTotalMapper;

    @Resource
    private StoreLocalService storeLocalService;

    @Resource
    private StoreOutsideService storeOutsideService;

    @Resource
    private MergeTaskMapper mergeTaskMapper;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private MaterialService materialService;

    @Resource
    private ContainerService containerService;

    @Resource
    private MergeTaskRecordService mergeTaskRecordService;

    @Override
    public PageResult<MergeTaskDao> queryAll(MergeTaskQueryCriteria criteria, Page<Object> page) {
        return PageUtil.toPage(mergeTaskMapper.findAll(criteria, page));
    }

    @Override
    public List<MergeTaskDao> queryAll(MergeTaskQueryCriteria criteria) {
        return mergeTaskMapper.findAll(criteria);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(MergeTaskDao resources) {
        mergeTaskMapper.insert(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(MergeTaskDao resources) {
        MergeTaskDao mergeTask = getById(resources.getTaskId());
        mergeTask.copy(resources);
        mergeTaskMapper.updateById(mergeTask);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<String> ids) {
        mergeTaskMapper.deleteBatchIds(ids);
    }

    @Override
    public void download(List<MergeTaskDao> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (MergeTaskDao mergeTask : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("任务状态", mergeTask.getTaskStatus());
            map.put("任务起点储位", mergeTask.getTaskStart());
            map.put("任务终点储位", mergeTask.getTaskEnd());
            map.put("载具码", mergeTask.getContainerCode());
            map.put("仓库", mergeTask.getFloor());
            map.put("建单账号", mergeTask.getCreateName());
            map.put("建单时间", mergeTask.getCreateDate());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    public List<MergeTaskDao> findByTaskByTaskId(String taskId) {
        LambdaQueryWrapper<MergeTaskDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MergeTaskDao::getTaskId, taskId);
        return baseMapper.selectList(wrapper);
    }

    public List<MergeTaskDao> findByTaskAll(MergeTaskDao mergeTask) {
        LambdaQueryWrapper<MergeTaskDao> wrapper = new LambdaQueryWrapper<>();
        if (mergeTask.getTaskId() != null) {
            wrapper.eq(MergeTaskDao::getTaskId, mergeTask.getTaskId());
        }
        if (mergeTask.getTaskStatus() != null) {
            wrapper.eq(MergeTaskDao::getTaskStatus, mergeTask.getTaskStatus());
        }
        if (mergeTask.getTaskStart() != null) {
            wrapper.eq(MergeTaskDao::getTaskStart, mergeTask.getTaskStart());
        }
        if (mergeTask.getTaskEnd() != null) {
            wrapper.eq(MergeTaskDao::getTaskEnd, mergeTask.getTaskEnd());
        }
        if (mergeTask.getContainerCode() != null) {
            wrapper.eq(MergeTaskDao::getContainerCode, mergeTask.getContainerCode());
        }
        if (mergeTask.getContainerStatus() != null) {
            wrapper.eq(MergeTaskDao::getContainerStatus, mergeTask.getContainerStatus());
        }
        if (mergeTask.getFloor() != null) {
            wrapper.eq(MergeTaskDao::getFloor, mergeTask.getFloor());
        }
        if (mergeTask.getCreateName() != null) {
            wrapper.eq(MergeTaskDao::getCreateName, mergeTask.getCreateName());
        }
        if (mergeTask.getCreateDate() != null) {
            wrapper.eq(MergeTaskDao::getCreateDate, mergeTask.getCreateDate());
        }
        return this.list(wrapper);
    }

    @Override
    public MergeTaskDao findByTaskByContainerCode(String containerCode) {
        LambdaQueryWrapper<MergeTaskDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MergeTaskDao::getContainerCode, containerCode);
        return this.getOne(wrapper);
    }

    public void updateWrapper(MergeTaskDao mergeTaskDao, LambdaUpdateWrapper<MergeTaskDao> wrapper) {
        if (mergeTaskDao.getTaskStatus() != null) {
            wrapper.set(MergeTaskDao::getTaskStatus, mergeTaskDao.getTaskStatus());
        }
        if (mergeTaskDao.getTaskStart() != null) {
            wrapper.set(MergeTaskDao::getTaskStart, mergeTaskDao.getTaskStart());
        }
        if (mergeTaskDao.getTaskEnd() != null) {
            wrapper.set(MergeTaskDao::getTaskEnd, mergeTaskDao.getTaskEnd());
        }
        if (mergeTaskDao.getContainerStatus() != null) {
            wrapper.set(MergeTaskDao::getContainerStatus, mergeTaskDao.getContainerStatus());
        }
        if (mergeTaskDao.getFloor() != null) {
            wrapper.set(MergeTaskDao::getFloor, mergeTaskDao.getFloor());
        }
        if (mergeTaskDao.getCreateDate() != null) {
            wrapper.set(MergeTaskDao::getCreateDate, mergeTaskDao.getCreateDate());
        }
        if (mergeTaskDao.getCreateName() != null) {
            wrapper.set(MergeTaskDao::getCreateName, mergeTaskDao.getCreateName());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateData(MergeTaskDao mergeTaskDao) {
        LambdaUpdateWrapper<MergeTaskDao> wrapper = new LambdaUpdateWrapper<>();
        if (mergeTaskDao.getTaskId() != null) {
            wrapper.eq(MergeTaskDao::getTaskId, mergeTaskDao.getTaskId());
            this.updateWrapper(mergeTaskDao, wrapper);
        }
        if (mergeTaskDao.getContainerCode() != null) {
            wrapper.eq(MergeTaskDao::getContainerCode, mergeTaskDao.getContainerCode());
            this.updateWrapper(mergeTaskDao, wrapper);
        }
        baseMapper.update(null, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatusTaskStart(String taskId) {
        LambdaUpdateWrapper<MergeTaskDao> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(MergeTaskDao::getTaskId, taskId);
        wrapper.eq(MergeTaskDao::getTaskStatus, ConstantStatus.MERGED_TO_BE);
        wrapper.set(MergeTaskDao::getTaskStatus, ConstantStatus.MERGED_IN_PROGRESS);
        wrapper.set(MergeTaskDao::getStartDate, new Timestamp(new Date().getTime()));
        return this.update(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatusTaskEnd(String containerCode, Integer taskStatus, Integer containerStatus) {
        LambdaUpdateWrapper<MergeTaskDao> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(MergeTaskDao::getContainerCode, containerCode);
        if (taskStatus != null) {
            wrapper.eq(MergeTaskDao::getTaskStatus, taskStatus);
        }
        if (containerStatus != null) {
            wrapper.set(MergeTaskDao::getContainerStatus, containerStatus);
        }
        this.update(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDataList(List<MergeTaskDao> taskDaoList) {
        this.saveBatch(taskDaoList);
    }


    /**
     * 流程第一步
     * 查询合箱/托任务清单
     *
     * @param criteria 可合箱/托任务查询对象
     * @return 可合箱/托任务查询结果
     */
    @Override
    public PageResult<MergeTaskDao> findMergeStoreTask(MergeTaskQueryCriteria criteria, Page<MergeTaskDao> page) {
        Page<MergeTaskDao> mergeStoreTask = mergeTaskMapper.findMergeStoreTask(criteria, page);
        PageResult<MergeTaskDao> pageResult = new PageResult<>();
        pageResult.setContent(mergeStoreTask.getRecords());
        pageResult.setTotalElements(mergeStoreTask.getTotal());
        return pageResult;
    }

    /**
     * 流程第二步
     *
     * @param mergeRequestVo 可合箱/托物料查询对象
     * @return 可合箱/托物料查询结果
     */
    @Override
    public PageResult<MergeCreateResponseVo> findMergeMaterialInfo(MergeRequestVo mergeRequestVo) {
        PageResult<MergeCreateResponseVo> pageResult = new PageResult<>();

        Page<MergeCreateResponseVo> page = new Page<>(mergeRequestVo.getPage(), mergeRequestVo.getSize());
        Page<MergeCreateResponseVo> mergeStoreMaterial = storeTotalMapper.findMergeAvailableMaterial(page, mergeRequestVo);
        List<MergeCreateResponseVo> records = mergeStoreMaterial.getRecords();
        if (records.isEmpty()) {
            pageResult.setTotalElements(0L);
            pageResult.setContent(Collections.emptyList());
            return pageResult;
        }
        pageResult.setTotalElements(mergeStoreMaterial.getTotal());
        for (MergeCreateResponseVo record : records) {
            String containerCode = record.getContainerCode();
            // 根据载具编码查询物料信息
            List<MaterialDao> materialList = materialService
                    .findDataDao(new MaterialDao().setContainerCode(containerCode));
            record.setMaterialList(materialList);
        }
        pageResult.setContent(records);
        return pageResult;
    }

    /**
     * 流程第三步
     * 创建合箱/板出库任务单
     *
     * @param request 请求合箱/托对象
     * @return 合箱/托结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> mergeCreateContainerInfo(MergeContainerRequestVo request) {
        List<String> containerCodeList = request.getContainerCodeList();
        if (containerCodeList.isEmpty()) {
            return Result.error("请选择容器!");
        }
        if (containerCodeList.size() < 2) {
            return Result.error("容器最少选择2个!");
        }
        String createName = request.getCreateName();
        if (createName == null || createName.isEmpty()) {
            return Result.error("任务创建人不能为空!");
        }

        String workIp = request.getWorkIP();
        String floor = "";
        String goodType = "";

        // 条件判断是否符合合箱要求
        Set<String> isFloor = new HashSet<>();
        Set<Integer> isDisable = new HashSet<>();
        for (String containerCode : containerCodeList) {
            MergeTaskDao byContainerCode = this.findByTaskByContainerCode(containerCode);
            if (byContainerCode != null) {
                return Result.error("容器" + containerCode + "已有合箱/托任务！");
            }
            StoreLocalDao storeLocalDao = storeLocalService
                    .findData(new StoreLocalDao().setContainerCode(containerCode));

            if (storeLocalDao == null) {
                continue;
            }
            // 根据载具编码查询物料信息
            List<MaterialDao> MaterialDaoList = materialService
                    .findDataDao(new MaterialDao().setContainerCode(containerCode));

            for (MaterialDao materialDao : MaterialDaoList) {
                Integer disable = materialDao.getDisable();
                isDisable.add(disable == null || disable == 0 ? 0 : disable);
                if (isDisable.size() > 1) {
                    return Result.error("冻结与非冻结物料不能进行合箱!");
                }
            }
            floor = storeLocalDao.getFloor();
            isFloor.add(storeLocalDao.getFloor());
            if (isFloor.size() > 1) {
                return Result.error("请选择相同楼层进行合箱!");
            }
        }

        // 判断是否有其他出库任务
//        Boolean isOutBoundTask = recordService.isRecordOutBoundTask();
//        if (isOutBoundTask) {
//            return Result.error("现在有其他出库任务！");
//        }

        if (floor.equals(ConstantStatus.M2_FLOOR)) {
            goodType = ConstantStatus.PICKING_AREA;
        }
        if (floor.equals(ConstantStatus.M1_FLOOR)) {
            goodType = ConstantStatus.SORTING_AREA;
        }


        try {
            // 写入出库任务单
            List<MergeTaskDao> taskDaoList = new ArrayList<>();

            Timestamp timestamp = new Timestamp(new Date().getTime());
            String taskId = String.valueOf(SnowIdUtil.nextId());
            for (String containerCode : containerCodeList) {
                StoreLocalDao storeLocalDao = storeLocalService
                        .findData(new StoreLocalDao().setContainerCode(containerCode));
                if (storeLocalDao == null) {
                    continue;
                }
                MergeTaskDao mergeTaskDao = new MergeTaskDao()
                        // 任务id
                        .setId(String.valueOf(SnowIdUtil.nextId()))
                        .setTaskId(taskId)
                        .setTaskStatus(ConstantStatus.MERGED_TO_BE)
                        // 任务储位信息
                        .setFloor(floor)
                        .setWorkIp(workIp)
                        .setGoodType(goodType)
                        // 任务启始与终点储位
                        .setTaskStart(storeLocalDao.getId())
                        // 载具编码与状态
                        .setContainerStatus(ConstantStatus.CONTAINER_TO_BE)
                        .setContainerCode(containerCode)
                        // 创建人、创建时间
                        .setCreateName(createName)
                        .setCreateDate(timestamp);
                taskDaoList.add(mergeTaskDao);

                // 更新库内储位状态
                StoreLocalDao storeLocal = new StoreLocalDao()
                        .setId(storeLocalDao.getId())
                        .setStatus(InboundStatusEnum.OUTBOUND_LOCK.status);
                storeLocalService.updateData(storeLocal);
            }
            this.saveDataList(taskDaoList);

        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
        return Result.success("创建合箱/托成功！");
    }


    /**
     * 流程第五步
     * 开启线程任务执行出库逻辑
     */
    @Override
    public void ScheduledFindStoreMergeTask() {
        MergeTaskDao taskDao = new MergeTaskDao()
                .setTaskStatus(ConstantStatus.MERGED_IN_PROGRESS)
                .setContainerStatus(ConstantStatus.CONTAINER_TO_BE);
        List<MergeTaskDao> mergeTaskList = this.findByTaskAll(taskDao);
        if (mergeTaskList.isEmpty()) {
            return;
        }
        while (!mergeTaskList.isEmpty()) {
            for (MergeTaskDao mergeTaskDao : mergeTaskList) {
                // 货位类型
                String goodType = mergeTaskDao.getGoodType();
                // 楼层
                String floor = mergeTaskDao.getFloor();
                // 工位ip
                String workIp = mergeTaskDao.getWorkIp();
                // 库外储位id
                List<String> storeIdList = new ArrayList<>();
                storeOutsideService.findAvailableStoreIdList(null, workIp, floor, goodType, storeIdList);
                if (storeIdList.isEmpty()) {
                    continue;
                }
                String outStoreId = storeIdList.get(0);
                // 赋值任务单数据
                mergeTaskDao.setContainerStatus(ConstantStatus.CONTAINER_OUTBOUND_ING);
                mergeTaskDao.setTaskEnd(outStoreId);
                try {
                    Result<?> result = this.MergeExecuteTransactional(mergeTaskDao);
                    if (result.getCode() != 200) {
                        mergeTaskLog.error("{} {}  {}", Thread.currentThread().getName(), mergeTaskDao.getTaskId(), result.getMessage());
                    }
                    MergeTest.TestOutMergeTask(mergeTaskDao);
                } catch (Exception e) {
                    mergeTaskLog.error("{} {}  {}", Thread.currentThread().getName(), mergeTaskDao.getTaskId(), e.getMessage());
                }
            }
            mergeTaskList = this.findByTaskAll(taskDao);
        }
    }


    /**
     * 流程第六步
     *
     * @param params 合箱/托任务id
     * @return 查询每个载具对应物料信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> startMergeTaskInfo(Map<String, String> params) {
        if (params == null || params.get("taskId") == null) {
            return Result.error("任务单号不能为空！");
        }
        String taskId = params.get("taskId");
        if (taskId == null) {
            return Result.error("任务单号不能为空！");
        }

        List<MergeTaskDao> mergeTaskList = this.findByTaskAll(new MergeTaskDao().setTaskId(taskId));
        if (mergeTaskList.isEmpty()) {
            return Result.error("任务单不存在");
        }
        for (MergeTaskDao mergeTaskDao : mergeTaskList) {
            if (mergeTaskDao.getTaskStatus().equals(ConstantStatus.MERGED_IN_PROGRESS)) {
                return Result.error(201, "请不要重复点击开启合并！");
            }
        }
        if (this.updateStatusTaskStart(taskId)) {
            return Result.success();
        }
        return Result.error(500, "开启合并失败！");
    }


    @Override
    public Result<List<MergeContainerList>> findMergeTaskInfo(Map<String, Object> params) {
        if (params == null || params.get("taskId") == null) {
            return Result.error("任务单号不能为空！");
        }
        String taskId = (String) params.get("taskId");
        List<MergeTaskDao> mergeTaskList = this.findByTaskByTaskId(taskId);

        List<MergeContainerList> containerList = new ArrayList<>();
        for (MergeTaskDao mergeTaskDao : mergeTaskList) {
            String containerCode = mergeTaskDao.getContainerCode();
            if (containerCode == null) {
                continue;
            }
            MergeTaskDao mergeTask = findByTaskByContainerCode(containerCode);
            // 根据载具编码查询物料信息
            List<MaterialDao> materialList = materialService
                    .findDataDao(new MaterialDao().setContainerCode(containerCode));
            MergeContainerList mergeContainer = new MergeContainerList();
            mergeContainer.setContainerCode(containerCode);
            mergeContainer.setContainerStatus(mergeTask.getContainerStatus());
            for (MaterialDao materialDao : materialList) {
                mergeContainer.setMaterialWeight(materialDao.getInventoryQuantity());
                mergeContainer.setItemBarCodeList(materialDao.getItemBarCode());
            }
            containerList.add(mergeContainer);
        }
        return Result.success(containerList);
    }

    /**
     * 流程第七步
     * 重新绑定物料信息到新载具
     *
     * @param itemBarCodeList 物料条码集合
     * @param containerCode   载具编码
     * @return 合箱/托结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> againBindContainerInfo(List<String> itemBarCodeList, String containerCode) {
        try {
            MaterialDao materialDao = new MaterialDao().setContainerCode(containerCode);
            materialService.updateDataByList(itemBarCodeList, materialDao);
            List<MaterialDao> MaterialList = materialService.findDataList(itemBarCodeList);
            List<MergeTaskRecordDao> mergeTaskRecordList = new ArrayList<>();
            for (MaterialDao dao : MaterialList) {
                MergeTaskRecordDao mergeTaskRecordDao = new MergeTaskRecordDao();
                String containerSource = dao.getContainerCode();
                MergeTaskDao mergeTaskDao = this.findByTaskByContainerCode(containerSource);
                if (mergeTaskDao == null) {
                    return Result.error("任务单不存在该物料源载具");
                }
                mergeTaskRecordDao.setId(String.valueOf(SnowIdUtil.nextId()));
                mergeTaskRecordDao.setContainerSource(containerSource);
                mergeTaskRecordDao.setContainerTarget(containerCode);
                mergeTaskRecordDao.setTaskId(mergeTaskDao.getTaskId());
                mergeTaskRecordDao.setFloor(mergeTaskDao.getFloor());
                mergeTaskRecordDao.setCreateName(mergeTaskDao.getCreateName());
                mergeTaskRecordDao.setCreateDate(mergeTaskDao.getCreateDate());
                mergeTaskRecordDao.setItemBarCode(dao.getItemBarCode());
                mergeTaskRecordDao.setWeight(dao.getIssuePosition());
                mergeTaskRecordList.add(mergeTaskRecordDao);
            }
            mergeTaskRecordService.saveBatch(mergeTaskRecordList);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
        return Result.success();
    }

    /**
     * 流程第八步
     *
     * @return 合箱/托结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> successBindContainer(Map<String, String> params) {
        if (params == null || params.get("containerCode") == null || Objects.equals(params.get("containerCode"), "")) {
            return Result.error("参数不能为空");
        }
        String containerCode = params.get("containerCode");
        MergeTaskDao mergeTaskDao = this.findByTaskByContainerCode(containerCode);
        if (mergeTaskDao == null) {
            return Result.error("任务单不存在该物料源载具！");
        }
        if (mergeTaskDao.getContainerStatus().equals(ConstantStatus.CONTAINER_MERGE_COMPLETED)) {
            return Result.error("该载具已经合并完成，请不要重复点击！");
        }
        try {
            return this.mergeInExecuteTransactional(mergeTaskDao);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }

    /**
     * 流程第九步
     *
     * @return 合箱/托结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> allSuccessBindContainer(String taskId) {
        List<MergeTaskDao> mergeTaskDaoList = this.findByTaskByTaskId(taskId);
        if (mergeTaskDaoList.isEmpty()) {
            return Result.error("不存在该任务单物！");
        }
        for (MergeTaskDao mergeTaskDao : mergeTaskDaoList) {
            if (mergeTaskDao == null) {
                continue;
            }
            Integer containerStatus = mergeTaskDao.getContainerStatus();
            if (!containerStatus.equals(ConstantStatus.CONTAINER_MERGE_COMPLETED)) {
                return Result.error("该任务单存在未完成的物料，请先完成合并！");
            }
        }
        LambdaUpdateWrapper<MergeTaskDao> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(MergeTaskDao::getTaskId, taskId);
        wrapper.set(MergeTaskDao::getTaskStatus, ConstantStatus.MERGED_COMPLETED);
        int update = baseMapper.update(null, wrapper);
        if (update > 0) {
            return Result.success("操作成功");
        } else {
            return Result.error("操作失败");
        }
    }

    @Override
    public Result<?> findExistTask() {
        LambdaQueryWrapper<MergeTaskDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(MergeTaskDao::getTaskId, MergeTaskDao::getTaskStatus);
        wrapper.groupBy(MergeTaskDao::getTaskId).groupBy(MergeTaskDao::getTaskStatus);
        List<MergeTaskDao> mergeTaskDaoList = baseMapper.selectList(wrapper);
        boolean flag = false;
        for (MergeTaskDao mergeTaskDao : mergeTaskDaoList) {
            if (mergeTaskDao.getTaskStatus() == null) {
                continue;
            }
            if (!mergeTaskDao.getTaskStatus().equals(ConstantStatus.MERGED_COMPLETED)) {
                flag = true;
                break;
            }
        }
        return Result.success(flag);
    }

    /**
     * 合箱更新储位-任务单信息-调用WCS出库
     *
     * @param mergeTaskDao 合箱/托任务单
     */
    public Result<?> MergeExecuteTransactional(MergeTaskDao mergeTaskDao) {
        // 创建出库AGV对象
        // 接口调用失败，标记事务回滚
        return transactionTemplate.execute(status -> {
            try {
                String outStoreId = mergeTaskDao.getTaskEnd();
                String goodType = mergeTaskDao.getGoodType();
                String containerCode = mergeTaskDao.getContainerCode();
                if (outStoreId == null || goodType == null) {
                    throw new RuntimeException("目的储位或货位类型为空");
                }
                StoreOutsideService storeOutsideService = SpringContextUtil.getBean(StoreOutsideService.class);
                MergeTaskService mergeTaskService = SpringContextUtil.getBean(MergeTaskService.class);
                MaterialService materialService = SpringContextUtil.getBean(MaterialService.class);
                // 根据载具编码查询物料信息
                List<MaterialDao> materialDaoList = materialService
                        .findDataDao(new MaterialDao().setContainerCode(containerCode));
                ContainerService containerService = SpringContextUtil.getBean(ContainerService.class);


                // 冻结物料出库要解冻
                boolean flag = false;
                List<String> freezeMesList = new ArrayList<>();
                for (MaterialDao materialDao : materialDaoList) {
                    Integer disable = materialDao.getDisable();
                    freezeMesList.add(materialDao.getItemBarCode());
                    flag = disable != null && disable.equals(ConstantStatus.FREEZE);
                }
                if (flag) {
                    // 冻结出库要解冻
                    ResponseResult<?> responseResult = MesNetworkRequest.materialUnfreezeReQuest(containerCode, freezeMesList);
                    if (responseResult.getReturnCode() != 200) {
                        throw new RuntimeException("解冻失败");
                    }
                }

                // 载具申请储位成功（锁定状态）
                ContainerDao containerDao = new ContainerDao()
                        .setId(containerCode)
                        .setIonLock(ConstantStatus.CONTAINER_LOCKED);
                containerService.updateDataById(containerDao);

                // 出库修改目的储位状态
                StoreOutsideDao storeOutsideDao = new StoreOutsideDao()
                        .setId(outStoreId)
                        .setStatus(InboundStatusEnum.INBOUND_LOCK.status);
                storeOutsideService.updateData(storeOutsideDao);

                // 修改任务单信息
                mergeTaskService.updateData(mergeTaskDao);
                // 创建出库AGV对象
                OutBoundTaskToWcsVo task = new OutBoundTaskToWcsVo()
                        .setContainerCode(mergeTaskDao.getContainerCode())
                        .setSource(mergeTaskDao.getTaskStart())
                        .setDestination(mergeTaskDao.getTaskEnd())
                        .setPriority(1)
                        .setFloor(mergeTaskDao.getFloor())
                        .setDeliveryType(ConstantStatus.InBound_Delivery_Type)
                        .setTaskType(ConstantStatus.Merge_OutBound_Type);
                // 调用WCS接口
                Result<?> result = WcsNetworkRequest.deliveryTask(task);
                if (result.getCode() != 200) {
                    throw new RuntimeException("目的储位或货位类型为空");
                }
                return Result.success();
            } catch (Exception e) {
                // 接口调用失败，标记事务回滚
                status.setRollbackOnly();
                return Result.error(e.getMessage());
            }
        });
    }

    /**
     * 合箱更新储位-任务单信息-调用WCS回库
     *
     * @param mergeTaskDao 合箱/托任务单
     */
    public Result<?> mergeInExecuteTransactional(MergeTaskDao mergeTaskDao) {
        // 创建出库AGV对象
        // 接口调用失败，标记事务回滚
        return transactionTemplate.execute(status -> {

            StoreOutsideService storeOutsideService = SpringContextUtil.getBean(StoreOutsideService.class);
            MergeTaskService mergeTaskService = SpringContextUtil.getBean(MergeTaskService.class);
            MaterialService materialService = SpringContextUtil.getBean(MaterialService.class);
            InboundService inboundService = SpringContextUtil.getBean(InboundService.class);
            ContainerService containerService = SpringContextUtil.getBean(ContainerService.class);

            // 载具编码
            String containerCode = mergeTaskDao.getContainerCode();
            // 库外储位
            String outStoreId = mergeTaskDao.getTaskEnd();
            // 楼层
            String floor = mergeTaskDao.getFloor();
            // 货位类型
            String goodType = mergeTaskDao.getGoodType();

            // 创建移库任务对象
            MergeTaskDao mergeTask = new MergeTaskDao()
                    .setContainerCode(containerCode)
                    .setContainerStatus(ConstantStatus.CONTAINER_MERGE_COMPLETED);

            // 根据载具编码查询物料信息
            List<MaterialDao> materialList = materialService
                    .findDataDao(new MaterialDao().setContainerCode(containerCode));

            try {
                if (materialList.isEmpty()) {
                    // 更新载具无货
                    ContainerDao containerDao = new ContainerDao()
                            .setId(containerCode)
                            .setIsExist(ConstantStatus.Out_OF_Stock);
                    containerService.updateDataById(containerDao);

                    // 修改目的储位状态
                    StoreOutsideDao storeOutsideDao = new StoreOutsideDao()
                            .setId(outStoreId)
                            .setStatus(InboundStatusEnum.STORAGE_FREE.status);
                    storeOutsideService.updateData(storeOutsideDao);

                    // 修改任务单信息
                    mergeTaskService.updateData(mergeTask);
                } else {
                    // 合箱回库
                    MesMaterialVo mesMaterialVo = new MesMaterialVo()
                            .setContainerCode(containerCode)
                            .setFloor(floor)
                            .setNest(true)
                            .setData(materialList);

                    Result<String> result = inboundService.InboundStorageApply(mesMaterialVo);
                    if (result.getCode() != 200) {
                        return Result.error("申请储位失败");
                    }
                    mergeTaskDao.setTaskStart(mergeTaskDao.getTaskEnd());
                    mergeTaskDao.setTaskEnd(result.getData());

                    String taskId = mergeTaskDao.getTaskId();
                    // 开始储位
                    String taskStart = mergeTaskDao.getTaskStart();
                    // 结束储位
                    String taskEnd = mergeTaskDao.getTaskEnd();
                    // 修改任务单信息
                    mergeTask.setTaskStart(taskStart).setTaskEnd(taskEnd);
                    mergeTaskService.update(mergeTask);

                    // 根据载具查询物料信息
                    String materialCodeListStr = materialService.getMaterialCodeListStrByContainerCode(containerCode);
                    OutBoundTaskToWcsVo task = new OutBoundTaskToWcsVo()
                            .setWmsTaskId(taskId)
                            .setContainerCode(containerCode)
                            .setSource(taskStart)
                            .setDestination(taskEnd)
                            .setPriority(PriorityEnum.MEDIUM.getWeight())
                            .setFloor(floor)
                            .setDeliveryType(ConstantStatus.Return_Delivery_Type)
                            .setTaskType(ConstantStatus.Merge_RetBound_Type)
                            .setMaterIalCode(materialCodeListStr);
                    Result<?> resultTask = WcsNetworkRequest.deliveryTask(task);
                    if (resultTask.getCode() != 200) {
                        throw new RuntimeException(resultTask.getMessage());
                    }

                    MergeTest.TestInMergeTask(this.findByTaskByContainerCode(containerCode));
                }
                return Result.success();
            } catch (Exception e) {
                // 接口调用失败，标记事务回滚
                status.setRollbackOnly();
                throw e;
            }
        });
    }
}
